#ifndef CASSIOPEIAMAIN_H
#define CASSIOPEIAMAIN_H

#include <Windows.h>
#include <tchar.h>
#include <map>

class CassiopeiaMain;

#include "resource.h"
#include "Utilities.h"
#include "TransparencyHelper.h"
#include "WindowReducer.h"
#include "Settings.h"
#include "Scheduler.h"
#include "GlassConsole.h"
#include "DeskNotes.h"
#include "AdvancedShowDesktop.h"
#include "DeskTidy.h"
#include "WindowGroups.h"
#include "DesktopPictureFrame.h"
#include "QuickButtons.h"
#include "Translation.h"

using namespace Translation;
using namespace std;

#pragma region defines

#define SystemMenu_MenuFirstID						0x003B

#define SystemMenu_TopMost							SystemMenu_MenuFirstID
#define SystemMenu_WindowReducing					(SystemMenu_MenuFirstID + 1)
#define SystemMenu_SendToBottom						(SystemMenu_MenuFirstID + 2)
#define SystemMenu_Separator1 						(SystemMenu_MenuFirstID + 3)

#define SystemMenu_WindowsRestoreThisProcess		(SystemMenu_MenuFirstID + 4)
#define SystemMenu_WindowsMinimizeThisProcess		(SystemMenu_MenuFirstID + 5)

#define SystemMenu_TransparencyOnLeave      		(SystemMenu_MenuFirstID + 6)
#define SystemMenu_Separator2						(SystemMenu_MenuFirstID + 7)
#define SystemMenu_TransparencyNone      			(SystemMenu_MenuFirstID + 8)
#define SystemMenu_TransparencyTen       			(SystemMenu_MenuFirstID + 9)
#define SystemMenu_TransparencyTwenty    			(SystemMenu_MenuFirstID + 10)
#define SystemMenu_TransparencyThirty    			(SystemMenu_MenuFirstID + 11)
#define SystemMenu_TransparencyForty     			(SystemMenu_MenuFirstID + 12)
#define SystemMenu_TransparencyFifty     			(SystemMenu_MenuFirstID + 13)
#define SystemMenu_TransparencySixty     			(SystemMenu_MenuFirstID + 14)
#define SystemMenu_TransparencySeventy   			(SystemMenu_MenuFirstID + 15)
#define SystemMenu_TransparencyEighty    			(SystemMenu_MenuFirstID + 16)
#define SystemMenu_TransparencyNinety    			(SystemMenu_MenuFirstID + 17)
#define SystemMenu_Separator3						(SystemMenu_MenuFirstID + 18)
#define SystemMenu_KillProcess						(SystemMenu_MenuFirstID + 19)
#define SystemMenu_WindowGroups						(SystemMenu_MenuFirstID + 20)
#define SystemMenu_WindowGroupsExclude				(SystemMenu_MenuFirstID + 21)
#define SystemMenu_Separator4						(SystemMenu_MenuFirstID + 22)

#define SystemMenu_WindowGroupsFirstID				(SystemMenu_MenuFirstID + 40)
#define SystemMenu_WindowGroupsLastID				(SystemMenu_WindowGroupsFirstID + 9)
																

#define EW_AddSystemMenuItems						0	
#define EW_RemoveSystemMenuItems					1	
#define EW_EnableWindowGroups						2	


#define TrayMenu_MenuFirstID						0

#define TrayMenu_GlassConsole						TrayMenu_MenuFirstID
#define TrayMenu_TransparencyOnMoveSize				(TrayMenu_MenuFirstID + 1)
#define TrayMenu_AdvancedShowDesktop				(TrayMenu_MenuFirstID + 2)
#define TrayMenu_DeskNotes							(TrayMenu_MenuFirstID + 3)
#define TrayMenu_DeskTidy							(TrayMenu_MenuFirstID + 4)
#define TrayMenu_SchedulerActive					(TrayMenu_MenuFirstID + 5)
#define TrayMenu_Separator1							(TrayMenu_MenuFirstID + 6)
#define TrayMenu_SchedulerSetAlert					(TrayMenu_MenuFirstID + 7)
//#define TrayMenu_KeyLockActive						(TrayMenu_MenuFirstID + 8)
//#define TrayMenu_KeyLockLockAtUnplug				(TrayMenu_MenuFirstID + 9)
//#define TrayMenu_Separator2							(TrayMenu_MenuFirstID + 10)
//#define TrayMenu_KeyLockLock						(TrayMenu_MenuFirstID + 11)
//#define TrayMenu_Separator3							(TrayMenu_MenuFirstID + 12)
//#define TrayMenu_KeyLockSetPrimaryDevice			(TrayMenu_MenuFirstID + 13)
//#define TrayMenu_KeyLockClearPrimaryDevice			(TrayMenu_MenuFirstID + 14)
//#define TrayMenu_Separator4							(TrayMenu_MenuFirstID + 15)
//#define TrayMenu_KeyLockSetSecondaryDevice			(TrayMenu_MenuFirstID + 16)
//#define TrayMenu_KeyLockClearSecondaryDevice		(TrayMenu_MenuFirstID + 17)
#define TrayMenu_Separator5							(TrayMenu_MenuFirstID + 18)
#define TrayMenu_ExtendedSystemMenu					(TrayMenu_MenuFirstID + 19)
#define TrayMenu_RefreshSystemMenu					(TrayMenu_MenuFirstID + 20)
#define TrayMenu_Separator6							(TrayMenu_MenuFirstID + 21)
#define TrayMenu_Close								(TrayMenu_MenuFirstID + 22)
#define TrayMenu_Separator7							(TrayMenu_MenuFirstID + 23)
#define TrayMenu_WindowsMinimizeAll					(TrayMenu_MenuFirstID + 24)
#define TrayMenu_WindowsRestoreAll					(TrayMenu_MenuFirstID + 25)
#define TrayMenu_WindowGroups						(TrayMenu_MenuFirstID + 26)
#define TrayMenu_DesktopPictureFrame				(TrayMenu_MenuFirstID + 27)
#define TrayMenu_QuickButtons						(TrayMenu_MenuFirstID + 28)
//#define TrayMenu_Separator8							(TrayMenu_MenuFirstID + x)

#define TrayMenu_LockDrivesFirstID					(TrayMenu_MenuFirstID + 80)
#define TrayMenu_LockDrivesLastID					(TrayMenu_LockDrivesFirstID + 20)

//#define TrayMenu_LanguagesFirstID					(TrayMenu_MenuFirstID + 105)
//#define TrayMenu_LanguagesLastID					(TrayMenu_LanguagesFirstID + 50)

	
#pragma endregion

class CassiopeiaMain
{
public:
	~CassiopeiaMain();

	bool Close();
	static CassiopeiaMain* CreateInstance(HINSTANCE hInstance);
private:
	CassiopeiaMain(HINSTANCE hInstance);

	bool Close(bool postQuitMsg);

	void AddSystemMenuItems(HWND hWnd);
	void InitTrayMenu();
	void StartComponents(HINSTANCE hInstance);
	bool StopComponents();

	HINSTANCE hInstance;
	HMENU trayMenu;
	NOTIFYICONDATA notifyIconData;
	HWND hWnd;
	BOOL dwmEnabled;
	DWORD processId;

	bool closed;
	bool extendedSystemMenu;

	TransparencyHelper * transparencyHelper;
	WindowReducer * windowReducer;
	
	GlassConsole * glassConsole;
	Scheduler * scheduler;
	DeskNotes * deskNotes;
	AdvancedShowDesktop * advancedShowDesktop;
	DeskTidy * deskTidy;
	//KeyLock * keyLock;
	WindowGroups * windowGroups;
	DesktopPictureFrame * desktopPictureFrame;
	QuickButtons * quickButtons;


	static UINT WM_TASKBARCREATED;
	static CassiopeiaMain* instance;
	static HWINEVENTHOOK hWinEventHook;
	static HHOOK hMouseHook;
	static bool mouseHookActive;

	static void GlassConsoleActiveChanged(CassiopeiaComponent* sender, bool active);
	static void SchedulerActiveChanged(CassiopeiaComponent* sender, bool active);
	static void DeskNotesActiveChanged(CassiopeiaComponent* sender, bool active);
	static void AdvancedShowDesktopActiveChanged(CassiopeiaComponent* sender, bool active);
	static void DeskTidyActiveChanged(CassiopeiaComponent* sender, bool active);
	//static void KeyLockActiveChanged(CassiopeiaComponent* sender, bool active);
	static void windowGroups_GroupNameChanged(WindowGroups* sender, int groupID, tstring newName);
	static void windowGroups_GroupSwitching(WindowGroups* sender, int groupID, bool* cancel);
	static void windowGroups_ActiveChanged(CassiopeiaComponent* sender, bool active);
	static void desktopPictureFrame_ActiveChanged(CassiopeiaComponent* sender, bool active);
	static void quickButtons_ActiveChanged(CassiopeiaComponent* sender, bool active);
	
	static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
	static VOID CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook,DWORD dwEvent,HWND hWnd,LONG idObject,LONG idChild,DWORD idEventThread,DWORD dwmsEventTime);
	static LRESULT CALLBACK MouseHookProc (int code,WPARAM wParam,LPARAM lParam);
	static BOOL CALLBACK EnumWindowsProc(HWND hWnd,LPARAM lParam);	
};

#endif